# -- coding: utf-8 --
"""
# MIAHX© 语音传感器数据帧消息的 FastDDS 发布/订阅器

**模块：MIAHX© / 框架基础服务层（FFST） / 交互框架信息表示模型（IFIRM）**

Version: 0.4.10,
Last updated: October 20, 2024

## Contributor(s)
* YAO Naiming <[naiming@iscas.ac.cn](mailto:naiming@iscas.ac.cn)>

## Change log
### v0.4.10
- .20: [优化] Reader 构造方法传入 topic_name
- .13: [更新] 适配新的消息定义，重命名，重新实现 write
- .11: [更新] 重命名 (deprecated)
- .9: [更新] 修复缺陷 (deprecated)
- .2: [更新] 适配新基类 (deprecated)
### v0.4.7
- .26: [优化] 初始实现

---
Copyright © 2024-2025 MIAHX Contributors, ISCAS, and ASIC. All Rights Reserved.
Licensed under Apache-2.0.
"""

import miahx_fastdds as dds
import numpy as np

from .. import Topics, Participant
from ..reader import Reader, ReaderListener
from ..writer import Writer


class SpeechStreamReader(Reader):
    def __init__(self, participant: Participant, on_data_listeners=None):
        topic_name = Topics.DEV_SPEECH
        topic_data_type = dds.SpeechDataFramePubSubType()
        super().__init__(participant, topic_name, topic_data_type,
                         listener=ReaderListener(topic_name, topic_data_type, on_data_listeners))


class SpeechStreamWriter(Writer):
    def __init__(self, participant: Participant,
                 stag: int = None, srate: int = None, schns: list[str] = None):
        super().__init__(participant, Topics.DEV_SPEECH, dds.SpeechDataFramePubSubType(),
                         stag=stag, srate=srate, schns=schns)

    def write(self, items: list[tuple[int, float, int, np.ndarray, str, list[str]]],
              iid: int = None, uts: float = None):
        # header
        frame = dds.SpeechDataFrame()
        frame.header(self._create_frame_header(uts, iid))
        # sample
        samples = []
        for item in items:
            iid, uts, swidth, rawdata, transcript, tokens = item
            sample = dds.SpeechSample()
            sample.iid(iid)
            sample.uts(uts)
            if rawdata is not None:
                assert swidth > 0
                dtype = getattr(np, f'int{swidth * 8}', np.int16)
                assert rawdata.dtype == dtype
                sample.swidth(swidth)
                sample.rawdata(rawdata.flatten().tolist())
            if transcript is not None:
                sample.transcript(transcript)
            if tokens is not None:
                sample.tokens(tokens)
            samples.append(sample)
        frame.samples(samples)
        #
        self._writer.write(frame)
